package com.hnit.controllers;

import com.hnit.service.AddressService;
import com.hnit.service.OrdersService;
import com.hnit.web.DTO.AddressDTO;
import com.hnit.web.DTO.OrdersDTO;
import com.hnit.web.DTO.OrdersDetailDTO;
import com.hnit.web.Utils.ResponseResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


/**
 * 订单详情相关控制器
 */
@Slf4j
@RestController
@RequestMapping("/orders/operation")
@Tag(name = "订单操作", description = "订单详情查看和操作相关接口")
public class OrderDetailController {

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private AddressService addressService;

    /**
     * 根据订单ID获取订单详情
     * GET /product/orders/operation/detail/{orderId}
     */
    @GetMapping("/detail/{orderId}")
    @Operation(summary = "获取订单详情", description = "根据订单ID获取订单详细信息，包含商品明细")
    public ResponseResult getOrderDetail(
            @PathVariable @Parameter(description = "订单ID") Long orderId,
            @RequestHeader("X-User-ID") @Parameter(hidden = true) Long currentUserId) {

        try {
            log.info("用户{}查询订单详情，订单ID: {}", currentUserId, orderId);

            // 1. 获取订单详情
            OrdersDTO orderDetail = ordersService.getOrderById(orderId);
            if (orderDetail == null) {
                return ResponseResult.error("订单不存在");
            }

            // 2. 权限校验 - 只能查看自己的订单
            if (!orderDetail.getUserId().equals(currentUserId)) {
                log.warn("用户{}尝试访问不属于自己的订单，订单ID: {}, 订单所有者: {}",
                        currentUserId, orderId, orderDetail.getUserId());
                return ResponseResult.error("无权访问该订单");
            }

            log.info("订单详情查询成功，订单ID: {}, 状态: {}", orderId, orderDetail.getOrderStatus());
            //地址详情获取
            AddressDTO addressDTO = addressService.getAddressById(orderDetail.getAddressId());
            OrdersDetailDTO ordersDetailDTO = new OrdersDetailDTO();
            ordersDetailDTO.setAddressDTO(addressDTO);
            ordersDetailDTO.setOrdersDTO(orderDetail);
            return ResponseResult.ok().setData(ordersDetailDTO);

        } catch (RuntimeException e) {
            log.warn("获取订单详情失败，订单ID: {}, 用户ID: {}, 错误: {}", orderId, currentUserId, e.getMessage());
            return ResponseResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("获取订单详情异常，订单ID: {}, 用户ID: {}", orderId, currentUserId, e);
            return ResponseResult.error("获取订单详情失败，请稍后重试");
        }
    }

    /**
     * 取消订单
     * PUT /product/orders/operation/cancel/{orderId}
     */
    @PutMapping("/cancel/{orderId}")
    @Operation(summary = "取消订单", description = "取消待支付状态的订单")
    public ResponseResult cancelOrder(
            @PathVariable @Parameter(description = "订单ID") Long orderId,
            @RequestHeader("X-User-ID") @Parameter(hidden = true) Long currentUserId) {

        try {
            log.info("用户{}尝试取消订单，订单ID: {}", currentUserId, orderId);

            // 1. 权限校验 - 先查询订单确认所有权
            OrdersDTO orderDetail = ordersService.getOrderById(orderId);
            if (orderDetail == null) {
                return ResponseResult.error("订单不存在");
            }

            if (!orderDetail.getUserId().equals(currentUserId)) {
                log.warn("用户{}尝试取消不属于自己的订单，订单ID: {}", currentUserId, orderId);
                return ResponseResult.error("无权操作该订单");
            }

            // 2. 取消订单
            boolean success = ordersService.cancelOrder(orderId);
            if (success) {
                log.info("订单取消成功，订单ID: {}, 用户ID: {}", orderId, currentUserId);
                return ResponseResult.ok("订单取消成功");
            } else {
                return ResponseResult.error("订单取消失败");
            }

        } catch (RuntimeException e) {
            log.warn("取消订单失败，订单ID: {}, 用户ID: {}, 错误: {}", orderId, currentUserId, e.getMessage());
            return ResponseResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("取消订单异常，订单ID: {}, 用户ID: {}", orderId, currentUserId, e);
            return ResponseResult.error("取消订单失败，请稍后重试");
        }
    }

    /**
     * 确认收货
     * PUT /product/orders/operation/confirm-receipt/{orderId}
     */
    @PutMapping("/confirm-receipt/{orderId}")
    @Operation(summary = "确认收货", description = "确认收到商品，订单状态变更为已签收")
    public ResponseResult confirmReceipt(
            @PathVariable @Parameter(description = "订单ID") Long orderId,
            @RequestHeader("X-User-ID") @Parameter(hidden = true) Long currentUserId) {

        try {
            log.info("用户{}尝试确认收货，订单ID: {}", currentUserId, orderId);

            // 1. 权限校验
            OrdersDTO orderDetail = ordersService.getOrderById(orderId);
            if (orderDetail == null) {
                return ResponseResult.error("订单不存在");
            }

            if (!orderDetail.getUserId().equals(currentUserId)) {
                log.warn("用户{}尝试确认收货不属于自己的订单，订单ID: {}", currentUserId, orderId);
                return ResponseResult.error("无权操作该订单");
            }

            // 2. 确认收货
            boolean success = ordersService.confirmReceipt(orderId);
            if (success) {
                log.info("确认收货成功，订单ID: {}, 用户ID: {}", orderId, currentUserId);
                return ResponseResult.ok("确认收货成功");
            } else {
                return ResponseResult.error("确认收货失败");
            }

        } catch (RuntimeException e) {
            log.warn("确认收货失败，订单ID: {}, 用户ID: {}, 错误: {}", orderId, currentUserId, e.getMessage());
            return ResponseResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("确认收货异常，订单ID: {}, 用户ID: {}", orderId, currentUserId, e);
            return ResponseResult.error("确认收货失败，请稍后重试");
        }
    }

    /**
     * 申请退款
     * POST /product/orders/operation/refund/{orderId}
     */
    @PostMapping("/refund/{orderId}")
    @Operation(summary = "申请退款", description = "对已支付的订单申请退款")
    public ResponseResult applyRefund(
            @PathVariable @Parameter(description = "订单ID") Long orderId,
            @RequestBody @Valid RefundRequestDTO refundRequest,
            @RequestHeader("X-User-ID") @Parameter(hidden = true) Long currentUserId) {

        try {
            log.info("用户{}申请退款，订单ID: {}, 理由: {}", currentUserId, orderId, refundRequest.getReason());

            // 1. 权限校验
            OrdersDTO orderDetail = ordersService.getOrderById(orderId);
            if (orderDetail == null) {
                return ResponseResult.error("订单不存在");
            }

            if (!orderDetail.getUserId().equals(currentUserId)) {
                log.warn("用户{}尝试对不属于自己的订单申请退款，订单ID: {}", currentUserId, orderId);
                return ResponseResult.error("无权操作该订单");
            }

            // 2. 检查订单状态 - 只有已支付待发货的订单可以申请退款
            if (!orderDetail.getOrderStatus().equals(2)) {
                return ResponseResult.error("该订单状态不允许申请退款");
            }

            // 3. 申请退款（这里需要你实现具体的退款逻辑）
            // boolean success = ordersService.applyRefund(orderId, refundRequest);

            // 暂时模拟成功
            log.info("退款申请提交成功，订单ID: {}, 用户ID: {}", orderId, currentUserId);
            return ResponseResult.ok("退款申请已提交，请等待处理");

        } catch (RuntimeException e) {
            log.warn("申请退款失败，订单ID: {}, 用户ID: {}, 错误: {}", orderId, currentUserId, e.getMessage());
            return ResponseResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("申请退款异常，订单ID: {}, 用户ID: {}", orderId, currentUserId, e);
            return ResponseResult.error("申请退款失败，请稍后重试");
        }
    }
}

/**
 * 退款申请DTO
 */
class RefundRequestDTO {
    @Parameter(description = "退款原因")
    private String reason;

    @Parameter(description = "详细描述")
    private String description;

    // getters and setters
    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}